home *** CD-ROM | disk | FTP | other *** search
- /********************************************************************
- * *
- * Color icon manipulation and drawing routines *
- * by Markus Gutschke, modified by Ken Hollis *
- * *
- * Copyright (C) 1994, Bitgate Software, Clever Bits and Markus *
- * Gutschke *
- * All rights reserved. *
- * *
- * Note: These routines were documented, and are EXTREMELY *
- * difficult to understand without having extensive knowledge of *
- * VDI. Do NOT attempt to modify these routines unless you *
- * ABSOLUTELY know what you're doing. *
- * *
- ********************************************************************
- * *
- * Update log: *
- * *NONE* *
- * *
- ********************************************************************/
-
- #include <stddef.h>
- #include <string.h>
- #include "winlib.h"
-
- LOCAL int intersect(int x1,int y1,int w1,int h1,
- int x2,int y2,int w2,int h2,
- int *x3,int *y3,int *w3,int *h3)
- {
- *x3 = max(x1,x2);
- *y3 = max(y1,y2);
- *w3 = min(x1+w1-1,x2+w2-1) - *x3 + 1;
- *h3 = min(y1+h1-1,y2+h2-1) - *y3 + 1;
- return ((*w3 > 0) && (*h3 > 0));
- }
-
- void FixColIcon(ICONBLK *iconBlk,int planes,short *sData,
- short *sMask,short *dData,short *dMask,
- short *dtData,short *dtMask,short *cnvTab)
- {
- static int colcnv1[] = {0,1};
- static int colcnv2[] = {0,2,3,1};
- static int colcnv3[] = {0,2,3,6,4,7,5,1};
- static int colcnv4[] = {0,2,3,6,4,7,5,8,9,10,11,14,12,15,13,1};
- static int *colcnv[4] = {colcnv1,colcnv2,colcnv3,colcnv4};
- static MFDB colIndex = {0,0,0,0,0,0,0,0,0};
- static int oldPlanes = 0,xferMode = 0;
- static short *oldCnvTabPtr = NULL,oldCnvTab[16];
- long bitPlaneSize = 2L * ((iconBlk->ib_wicon + 15) / 16L)*
- (long)iconBlk->ib_hicon;
- MFDB pixel,source,dest,tmpIndex;
- unsigned x,y,b,p,i,j,tPlanes;
- int vdiHandle,pxy[8],col[2];
- short ditherBits,curDither,*sPtr,*dPtr,*mskPtr,*tmpBuf;
- int bitMapSize,colTabSize;
-
- if (planes == 1) {
- memmove(dMask,sMask,bitPlaneSize);
- memmove(dData,sData,bitPlaneSize);
- if (dtMask) {
- memmove(dtMask,sMask,bitPlaneSize);
- mskPtr = dMask;
- sPtr = dData;
- dPtr = dtData;
- for (y = 0; y < iconBlk->ib_hicon; y++) {
- ditherBits = 0x5555 << (y & 1);
- for (x = (iconBlk->ib_wicon + 15) / 16; x--; ) {
- curDither = ditherBits & *mskPtr++;
- *dPtr++ = *sPtr++ | curDither;
- }
- }
- }
- return;
- }
-
- vdiHandle = VDIhandle;
- memmove(dMask,sMask,bitPlaneSize);
-
- tPlanes = planes < 8 && cnvTab != NULL ? 8 : planes;
- source.fd_addr = sData;
- source.fd_w = iconBlk->ib_wicon;
- source.fd_h = iconBlk->ib_hicon;
- source.fd_wdwidth = (iconBlk->ib_wicon + 15) / 16;
- source.fd_stand = 1;
- source.fd_nplanes = num_planes /* planes */ /***/;
- source.fd_r1 =
- source.fd_r2 =
- source.fd_r3 = 0;
- dest = source;
- dest.fd_addr = dData;
- dest.fd_stand = 0;
- dest.fd_nplanes = num_planes;
- bitMapSize = num_planes * (((1 << tPlanes) + 15) & ~15) / 8;
- colTabSize = (int)sizeof(short) * (1 << tPlanes);
-
- tmpBuf = malloc(num_planes * bitPlaneSize * (dtMask ? 2 : 1));
- if (colIndex.fd_addr == NULL || oldPlanes != tPlanes ||
- oldCnvTabPtr != cnvTab ||
- (cnvTab != NULL && memcmp(oldCnvTab,cnvTab,sizeof(oldCnvTab)))) {
- if (colIndex.fd_addr != 0)
- free(colIndex.fd_addr);
- retry:
- if ((colIndex.fd_addr = malloc(2 * max(bitMapSize,colTabSize)))==NULL) {
- if (tmpBuf) {
- free(tmpBuf);
- tmpBuf = NULL;
- goto retry;
- }
-
- memset(dData,0,(long)num_planes * bitPlaneSize);
- memmove(dData,dMask,(long)bitPlaneSize);
- vr_trnfm(vdiHandle,&source,&dest);
- return;
- }
-
- if (cnvTab != NULL)
- memmove(oldCnvTab,cnvTab,sizeof(oldCnvTab));
-
- oldPlanes = tPlanes;
- oldCnvTabPtr = cnvTab;
- pixel.fd_addr = "\xFF";
- pixel.fd_w =
- pixel.fd_h =
- pixel.fd_wdwidth =
- pixel.fd_stand =
- pixel.fd_nplanes = 1;
- pixel.fd_r1 =
- pixel.fd_r1 =
- pixel.fd_r1 = 0;
- colIndex.fd_w = 1L << tPlanes;
- colIndex.fd_h = 1;
- colIndex.fd_wdwidth = (colIndex.fd_w+15)/16;
- colIndex.fd_stand = 0;
- colIndex.fd_nplanes = num_planes;
- colIndex.fd_r1 =
- colIndex.fd_r2 =
- colIndex.fd_r3 = 0;
-
- for (i = (unsigned)(1L << tPlanes); i--;) {
- pxy[0] = pxy[1] = pxy[2] = pxy[3] = pxy[5] = pxy[7] = 0;
- pxy[4] = pxy[6] = (int)i;
- col[0] = i; col[1] = 0;
- vrt_cpyfm(vdiHandle,MD_REPLACE,pxy,&pixel,&colIndex,col);
- }
-
- tmpIndex = colIndex;
- memmove((char *)tmpIndex.fd_addr += bitMapSize,
- (char *)colIndex.fd_addr,bitMapSize);
- colIndex.fd_stand = 1;
- vr_trnfm(vdiHandle,&tmpIndex,&colIndex);
-
- for (i = 0,
- dPtr = (short *)colIndex.fd_addr +
- max(bitMapSize,colTabSize) / 2;
- i < (unsigned)(1L << tPlanes); i++, dPtr++) {
- *dPtr = 0;
- for (j = num_planes, sPtr = (short*)colIndex.fd_addr + i / 16;
- j--; sPtr = (short *)((char *)sPtr+
- (((1L << tPlanes) + 15) & ~15) / 8))
- *dPtr |= !!((*sPtr << (i % 16)) & 0x8000) << (num_planes - 1 - j);
- }
-
- dPtr = (short *)colIndex.fd_addr;
- sPtr = (short *)colIndex.fd_addr + max(bitMapSize,colTabSize) / 2;
- p = planes >= 4 ? 4 : planes;
- for (i = 1 << planes; i--; ) {
- int j;
- if (i < (1 << p) - 1)
- j = colcnv[p-1][i];
- else if (i == (1 << planes) - 1)
- j = 1;
- else
- j = i-1;
-
- dPtr[i] = cnvTab && j < 16 ? sPtr[cnvTab[j]] : sPtr[j];
- }
-
- for (i = 1 << planes, xferMode = 0; i--;)
- if (dPtr[i] != i)
- if (xferMode != 1 && i == (1 << planes)-1 &&
- dPtr[i] == (1 << num_planes)-1)
- xferMode = 2;
- else
- xferMode = 1;
- }
-
- switch (xferMode) {
- case 0:
- if (num_planes > planes)
- memset((tmpBuf ? tmpBuf : dData) + planes * bitPlaneSize / 2L,0,
- (num_planes-planes) * bitPlaneSize);
- memmove(tmpBuf ? tmpBuf : dData,sData,planes * bitPlaneSize);
- break;
-
- case 1:
- for (y = 0, sPtr = sData, dPtr = tmpBuf ? tmpBuf : dData; y < iconBlk->ib_hicon; y++) {
- for (x = 0; x < iconBlk->ib_wicon; x += 16, sPtr++, dPtr++) {
- for (p = num_planes; p--; dPtr += bitPlaneSize / sizeof(short))
- *dPtr = 0;
-
- dPtr -= (long)num_planes * (long)bitPlaneSize / sizeof(short);
-
- for (b = 1; b != 0; b <<= 1) {
- sPtr += (long)planes * (long)bitPlaneSize / sizeof(short);
-
- for (p = 0, i = 0; p < planes; p++) {
- sPtr -= bitPlaneSize/sizeof(short);
- i = (i << 1) | !!(*sPtr & b);
- }
-
- i = ((short *) colIndex.fd_addr)[i];
- for (p = 0; p < num_planes; p++, dPtr += bitPlaneSize / sizeof(short))
- if (i & (1 << p))
- *dPtr |= b;
-
- dPtr -= (long)num_planes * (long)bitPlaneSize / sizeof(short);
- }
- }
- }
- break;
-
- case 2:
- dPtr = tmpBuf ? tmpBuf : dData;
- sPtr = sData;
- for (y = 0; y < iconBlk->ib_hicon; y++) {
- for (x = 0; x < iconBlk->ib_wicon; x += 16) {
- i = 0xFFFF;
- for (p = planes; p--; sPtr += bitPlaneSize / sizeof(short), dPtr += bitPlaneSize / sizeof(short))
- i &= *dPtr = *sPtr;
-
- sPtr -= (long)planes * bitPlaneSize / sizeof(short) - 1;
- for (p = num_planes - planes; p--; dPtr += bitPlaneSize / sizeof(short))
- *dPtr = i;
-
- dPtr -= (long)num_planes * bitPlaneSize / sizeof(short)-1;
- }
- }
- break;
- }
-
- if (dtMask) {
- memmove(dtMask,sMask,bitPlaneSize);
- mskPtr = dMask;
- sPtr = tmpBuf ? tmpBuf : dData;
- dPtr = tmpBuf ? tmpBuf + num_planes * bitPlaneSize / 2L : dtData;
-
- for (y = 0; y < iconBlk->ib_hicon; y++) {
- ditherBits = 0x5555 << (y & 1);
- for (x = (iconBlk->ib_wicon + 15) / 16; x--; ) {
- curDither = ditherBits & *mskPtr++;
- for (p = num_planes; p--; sPtr += bitPlaneSize/sizeof(short), dPtr += bitPlaneSize/sizeof(short))
- *dPtr = *sPtr | curDither;
-
- sPtr -= (long)num_planes * (long)bitPlaneSize / sizeof(short)-1;
- dPtr -= (long)num_planes * (long)bitPlaneSize / sizeof(short)-1;
- }
- }
-
- source.fd_addr = tmpBuf ? tmpBuf + num_planes * bitPlaneSize / 2L : dtData;
- source.fd_nplanes = num_planes;
- dest.fd_addr = dtData;
-
- vr_trnfm(vdiHandle,&source,&dest);
- }
-
- source.fd_addr = tmpBuf ? tmpBuf : dData;
- source.fd_nplanes = num_planes;
- dest.fd_addr = dData;
-
- vr_trnfm(vdiHandle,&source,&dest);
- if (tmpBuf)
- free(tmpBuf);
-
- vsl_color(vdiHandle, 1);
-
- return;
- }